package com.example.fengyungo.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.fengyungo.constant.MessageConstant;
import com.example.fengyungo.constant.MessageListConstant;
import com.example.fengyungo.constant.MsgConstant;
import com.example.fengyungo.domain.pojo.DriverMessageList;
import com.example.fengyungo.domain.pojo.Message;
import com.example.fengyungo.domain.pojo.UserMessageList;
import com.example.fengyungo.result.Result;
import com.example.fengyungo.service.MessageService;
import com.example.fengyungo.websocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;

@RestController
@RequestMapping("/message")
public class MessageController {

    @Autowired
    private MessageService messageService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    WebSocketServer webSocketServer;

    /**
     * 清理缓存数据
     * @param pattern String
     */
    private void cleanCache(String pattern){
        Set keys = redisTemplate.keys(pattern);
        redisTemplate.delete(keys);
    }

    /**
     * 根据司机id获取消息列表
     * @param driverId 司机id
     * @return Result<List<MessageList>>
     */
    @GetMapping("/driver/{driverId}")
    @Cacheable(value = "messageList",key = "'getMessageListByDriverId'+#driverId")
    public Result<List<DriverMessageList>> getMessageListByDriverId(@PathVariable String driverId){
        List<DriverMessageList> messageListByDriverId = messageService.getMessageListByDriverId(driverId);
        return Result.success(messageListByDriverId);
    };

    /**
     * 获取司机与用户的聊天记录
     * @param driverId 司机id
     * @param userId 用户id
     * @param num 聊天记录数量
     * @return Result
     */
    @GetMapping("/messages/{driverId}/{userId}/{num}")
    @Cacheable(value = "message",key = "'getMessagesByDriverIdAndUserId'+#driverId+#userId+#num")
    public Result<List<Message>> getMessages(@PathVariable String driverId, @PathVariable String userId,@PathVariable int num) {
        List<Message> messages = messageService.getMessagesByDriverIdAndUserId(driverId, userId,num);
        return Result.success(messages);
    }

    /**
     * 更新司机未读消息数量
     * @param driverId 司机id
     * @param userId 用户id
     * @param driverUnread 司机未读数
     * @return Result
     */
    @PutMapping("/updateDriverUnread/{driverId}/{userId}/{driverUnread}")
    public Result<Integer> updateDriverUnread(@PathVariable String driverId, @PathVariable String userId,@PathVariable Integer driverUnread) {
        Integer res = messageService.updateDriverUnread(driverId, userId, driverUnread);
        // 清理缓存
        cleanCache("fengyungomessage*");
        return Result.success(res);
    }

    /**
     * 根据用户id获取用户的消息列表
     * @param userId 用户id
     * @return 用户消息列表
     */
    @GetMapping("/user/{userId}")
    @Cacheable(value = "messageList",key = "'getMessageListByUserId'+#userId")
    public Result<List<UserMessageList>> getUserMessageListByUserId(@PathVariable String userId) {
        List<UserMessageList> messageListByUserId = messageService.getMessageListByUserId(userId);
        return Result.success(messageListByUserId);
    }

    /**
     * 更新用户未读消息数量
     * @param driverId 司机id
     * @param userId 用户id
     * @param userUnread 司机未读数
     * @return Result
     */
    @PutMapping("/updateUserUnread/{driverId}/{userId}/{userUnread}")
    public Result<Integer> updateUserUnread(@PathVariable String driverId, @PathVariable String userId,@PathVariable Integer userUnread) {
        Integer res = messageService.updateUserUnread(driverId, userId, userUnread);
        // 清理缓存
        cleanCache("fengyungomessage*");
        return Result.success(res);
    }

    /**
     * 发起聊天
     * @param driverId 司机id
     * @param userId 用户id
     * @return Result
     */
    @PostMapping("/addMessageList/{driverId}/{userId}")
    public Result<Boolean> addMessageList(@PathVariable String driverId, @PathVariable String userId) {
        // 先分别对司机和用户的消息列表进行查询，如果不存在才新增
        Integer res1 = messageService.updateDriverMessageListStatus(driverId, userId, MessageListConstant.EXISTENCE);
        Integer res2 = messageService.updateUserMessageListStatus(driverId, userId, MessageListConstant.EXISTENCE);
        if (res1 >= 1 || res2 >= 1) {
            // 清理缓存
            cleanCache("fengyungomessage*");
            return Result.success();
        }
        Boolean res = messageService.addMessageList(userId, driverId);
        if (res) {
            // 清理缓存
            cleanCache("fengyungomessage*");
            return Result.success();
        } else {
            return Result.error(MsgConstant.CAN_NOT_ADD_MESSAGE_LIST);
        }
    }

    /**
     * 添加消息到数据库中
     * @param message Message
     * @return Result
     */
    @PostMapping("/addMessage")
    public Result addMessage(@RequestBody Message message) {
        Integer res = messageService.insertMessage(message);
        if (res > 0) {
            // 发送给用户
            String messageString = JSONObject.toJSONString(message);
            webSocketServer.sendToClient(message.getReceiverId(), messageString);
            String senderId = message.getSenderId();
            String receiverId = message.getReceiverId();
            String driverId;
            String userId;
            // 修改司机消息列表的内容和时间
            messageService.updateDriverLastContentAndTime(message);
            // 修改用户消息列表的内容和时间
            messageService.updateUserLastContentAndTime(message);
            // 判断发送方和接收方用户的身份
            // 发送方为用户，接收方为司机
            if (senderId.charAt(0) == 'u') {
                userId = senderId;
                driverId = receiverId;
                // 修改司机的未读数
                Integer driverUnread = messageService.getDriverUnread(driverId, userId);
                messageService.updateDriverUnread(driverId, userId, driverUnread + 1);
            } else {
                // 发送方为司机，接收方为用户
                userId = receiverId;
                driverId = senderId;
                // 修改用户的未读数
                Integer userUnread = messageService.getUserUnread(driverId, userId);
                messageService.updateUserUnread(driverId, userId, userUnread + 1);
            }
            // 清理缓存
            cleanCache("fengyungomessage*");
            return Result.success(res);
        }
        return Result.error(MessageConstant.MESSAGE_SEND_FAILED);
    };
}
